package logic

import (
	"context"
	"database/sql"
	"easychat/apps/social/socialmodels"
	"easychat/pkg/constants"
	"easychat/pkg/xerr"
	"github.com/pkg/errors"
	"time"

	"easychat/apps/social/rpc/internal/svc"
	"easychat/apps/social/rpc/social"

	"github.com/zeromicro/go-zero/core/logx"
)

type GroupPutinLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGroupPutinLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GroupPutinLogic {
	return &GroupPutinLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GroupPutinLogic) GroupPutin(in *social.GroupPutinReq) (*social.GroupPutinResp, error) {
	var (
		inviteGroupMember *socialmodels.GroupMembers
		userGroupMember   *socialmodels.GroupMembers
		groupInfo         *socialmodels.Groups

		err error
	)

	userGroupMember, err = l.svcCtx.GroupMembersModel.FindByGroupIdAndUid(l.ctx, in.ReqId, in.GroupId)
	if err != nil && err != socialmodels.ErrNotFound {
		return nil, errors.Wrapf(xerr.NewDBErr(), "【查询群成员失败】 err: %v, req: %v ", err, in)
	}
	if userGroupMember != nil {
		return &social.GroupPutinResp{}, nil
	}

	groupReq, err := l.svcCtx.GroupRequestsModel.FindByGroupIdAndReqId(l.ctx, in.GroupId, in.ReqId)
	if err != nil && err != socialmodels.ErrNotFound {
		return nil, errors.Wrapf(xerr.NewDBErr(), "【查询群申请失败】 err: %v, req: %v ", err, in)
	}
	if groupReq != nil {
		return &social.GroupPutinResp{}, nil
	}

	groupReq = &socialmodels.GroupRequests{
		GroupId: in.GroupId,
		ReqId:   in.ReqId,
		ReqMsg: sql.NullString{
			String: in.ReqMsg,
			Valid:  true,
		},
		ReqTime: sql.NullTime{
			Time:  time.Unix(in.ReqTime, 0),
			Valid: true,
		},
		JoinSource: sql.NullInt64{
			Int64: int64(in.JoinSource),
			Valid: true,
		},
		InviterUserId: sql.NullString{
			String: in.InviterUid,
			Valid:  true,
		},
		HandleResult: sql.NullInt64{
			Int64: int64(constants.NoHandlerResult),
			Valid: true,
		},
	}

	createGroupMember := func() {
		if err != nil {
			return
		}
		err = l.createGroupMember(in)
	}

	groupInfo, err = l.svcCtx.GroupsModel.FindOne(l.ctx, in.GroupId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewDBErr(), "【查询群失败】 err: %v, req: %v ", err, in)
	}

	// 验证是否要验证
	if !groupInfo.IsVerify {
		// 直接创建群成员
		defer createGroupMember()

		groupReq.HandleResult = sql.NullInt64{
			Int64: int64(constants.PassHandlerResult),
			Valid: true,
		}

		return l.createGroupReq(groupReq, true)
	}

	// 验证方式
	if constants.GroupJoinSource(in.JoinSource) == constants.PutInGroupJoinSource {
		_, _ = l.createGroupReq(groupReq, false)
	}

	inviteGroupMember, err = l.svcCtx.GroupMembersModel.FindByGroupIdAndUid(l.ctx, in.InviterUid, in.GroupId)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewDBErr(), "【查询群成员失败2】 err: %v, req: %v ", err, in)
	}
	if constants.GroupRoleLevel(inviteGroupMember.RoleLevel) == constants.CreatorGroupRoleLevel || constants.GroupRoleLevel(inviteGroupMember.RoleLevel) == constants.ManagerGroupRoleLevel {
		// 创建群成员
		defer createGroupMember()

		groupReq.HandleResult = sql.NullInt64{
			Int64: int64(constants.PassHandlerResult),
			Valid: true,
		}
		groupReq.HandleUserId = sql.NullString{
			String: in.InviterUid,
			Valid:  true,
		}

		return l.createGroupReq(groupReq, true)
	}

	return l.createGroupReq(groupReq, false)
}

func (l *GroupPutinLogic) createGroupReq(groupReq *socialmodels.GroupRequests, isPass bool) (*social.GroupPutinResp, error) {
	groupReq.HandleTime = sql.NullTime{
		Time:  time.Now(),
		Valid: true,
	}
	_, err := l.svcCtx.GroupRequestsModel.Insert(l.ctx, groupReq)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewDBErr(), "【群申请失败】 err: %v", err)
	}

	if isPass {
		return &social.GroupPutinResp{
			GroupId: groupReq.GroupId,
		}, nil
	}

	return &social.GroupPutinResp{}, nil
}

func (l *GroupPutinLogic) createGroupMember(in *social.GroupPutinReq) error {
	groupMember := &socialmodels.GroupMembers{
		GroupId:   in.GroupId,
		UserId:    in.ReqId,
		RoleLevel: int64(constants.AtLargeGroupRoleLevel),
		JoinTime: sql.NullTime{
			Time:  time.Now(),
			Valid: true,
		},
		OperatorUid: sql.NullString{
			String: in.InviterUid,
			Valid:  true,
		},
	}

	_, err := l.svcCtx.GroupMembersModel.Insert(l.ctx, nil, groupMember)
	if err != nil {
		return errors.Wrapf(xerr.NewDBErr(), "【创建群成员失败】 err: %v, req: %v ", err, in)
	}

	return nil
}
